package com.ruoyi.erp.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.util.StringUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.erp.domain.*;
import com.ruoyi.erp.domain.Department;
import com.ruoyi.erp.domain.Fitemss00;
import com.ruoyi.erp.domain.HrHiPerson;
import com.ruoyi.erp.domain.Person;
import com.ruoyi.erp.domain.Vendor;
import com.ruoyi.erp.service.*;
import com.ruoyi.system.service.ISysDictDataService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

import static com.ruoyi.erp.controller.LedyFeeCheckinController.initAccvouch;

/**
 * 预算管理Controller
 *
 * @author ztj
 * @date 2025-11-14
 */
@RestController
@RequestMapping("/erp/budget")
public class LedyBudgetController extends BaseController {
    @Autowired
    private ILedyBudgetService ledyBudgetService;
    @Autowired
    private ILedyBudgetShareService ledyBudgetShareService;
    @Autowired
    private IGlAccvouchService glAccvouchService;
    @Autowired
    private ILedyBacFeeConfigService configService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IGlCashtableService cashtableService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IHrHiPersonService hrHiPersonService;
    @Autowired
    private IPersonService personService;
    @Autowired
    private IFitemss00Service fitemss00Service;
    @Autowired
    private IFitemss97classService fitemss97classService;
    @Autowired
    private IVendorService vendorService;

    @Log(title = "凭证生成", businessType = BusinessType.IMPORT)
    @GetMapping("/sync/{ids}/{type}")
    public AjaxResult faSync(@PathVariable Long[] ids, @PathVariable String type, LedyBudget ledyOuterFeeCollect) {
        List<LedyBudget> checkins = ledyBudgetService.selectLedyBudgetByIds(ids);
        GlAccvouch accvouch = new GlAccvouch();
        GlAccvouch accvouchQuery = new GlAccvouch();
        List<LedyBacFeeConfig> confList = initAccvouch(ledyOuterFeeCollect.getDbillDate(), "budget", glAccvouchService, configService, type, accvouch, accvouchQuery);
        final int[] i = {0};
        StringBuilder errTip = new StringBuilder();
        checkins.forEach(item -> {
            insertUser(i, glAccvouchService, type, accvouch, accvouchQuery);
            confList.forEach(conf -> {
                if (!conf.getItemId().equals(item.getCitemId())) {
//                    errTip.append(item.getVouchId() + "不匹配预算类型:" + item.getcVouType() + "\n");
                    return;
                }
                errTip.append(item.getVouchId());
                i[0]++;
                initAux(conf, confList, item, accvouch, departmentService, personService, fitemss97classService, vendorService, fitemss00Service, hrHiPersonService);
                accvouch.setInid(Long.parseLong(i[0] + ""));
                accvouch.setCcode(conf.getCcode());
                accvouch.setMd("0");
                accvouch.setMc("0");
                if (conf.getIshare() == 2) {
                    item.setMd(item.getMd().multiply(conf.getShareRatio()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
                }
                if (conf.getRecordCate().equals("借")) {
                    accvouch.setMd(item.getMd().toString());
                } else {
                    accvouch.setMc(item.getMd().toString());
                }

                if (new BigDecimal(accvouch.getMc()).compareTo(new BigDecimal(0)) == 0 && new BigDecimal(accvouch.getMd()).compareTo(new BigDecimal(0)) == 0) {
                    i[0]--;
                    return;
                }
                accvouch.setCdigest("预算支出：" + item.getVouchId() + item.getcVouType() + item.getCsupName());
                accvouch.setCcodeEqual(confList.stream().map(s -> {
                    if (!s.getCcode().equals(conf.getCcode()) && !s.getRecordCate().equals(conf.getRecordCate())) {
                        if (item.getMd().compareTo(new BigDecimal(0)) <= 0) {
                            return null;
                        }
                        return s.getCcode();
                    } else return null;
                }).distinct().collect(Collectors.joining(",")).replaceAll("null,", "").replace(",null", ""));
                accvouch.setCcodeexchEqual(accvouch.getCcodeEqual());
                glAccvouchService.insertGlAccvouch(accvouch);
                if (StringUtil.isNotEmpty(conf.getCashDesc())) {
                    GlCashtable cashtable = new GlCashtable();
                    BeanUtil.copyProperties(accvouch, cashtable);
                    cashtable.setcCashItem(conf.getCashDesc());
                    cashtableService.insertGlCashtable(cashtable);
                }
                LedyBudget feeCollect = new LedyBudget();
                feeCollect.setId(item.getId());
                feeCollect.setInoId(accvouch.getInoId().toString());
                feeCollect.setIflagRe(1);
                feeCollect.setDbillDate(accvouch.getDbillDate());
                ledyBudgetService.updateLedyBudget(feeCollect);
            });


        });
        if (errTip.toString().isEmpty()) {
            return error(errTip + "科目规则不匹配！");
        }
        return toAjax(1);
    }

    static void initAux(LedyBacFeeConfig conf, List<LedyBacFeeConfig> confList, LedyBudget item, GlAccvouch accvouch, IDepartmentService departmentService, IPersonService personService, IFitemss97classService fitemss97classService, IVendorService vendorService, IFitemss00Service fitemss00Service, IHrHiPersonService hrHiPersonService) {
        //                if (conf.getAuxiliaryTerm().contains("ccusId")) {
//                    insertUser(customerService, accvouch, item.getCcusName());
//                } else {
//                    accvouch.setCcusId(null);
//                }
        if (conf.getAuxiliaryTerm().contains("dept")) {
            Department department = new Department();
            department.setcDepName(item.getCdeptName());
            department.setcDepCode(StringUtils.substring(item.getCdeptId(), 0, 12));
            List<Department> departmentList = departmentService.selectDepartmentList(department);
            if (!departmentList.isEmpty()) {
                accvouch.setCdeptId(departmentList.get(0).getcDepCode());
            } else {
//                        List<Department> departmentListMax = departmentService.selectDepartmentList(new Department());
                department.setcDepFullName(item.getCdeptName());
                department.setbDepEnd("1");
                department.setiDepGrade("1");
//                    department.setdDepBeginDate();时间戳自动获取当前时间
//                        String numDep = departmentListMax.get(0).getcDepCode();
//                        int number = Integer.parseInt(numDep);
//                        number++;
//                        String paddedStr = String.format("%0" + numDep.length() + "d", number);
                department.setcDepCode(StringUtils.substring(item.getCdeptId(), 0, 12));
                departmentService.insertDepartment(department);
                accvouch.setCdeptId(department.getcDepCode());
            }
        } else {
            accvouch.setCdeptId(null);
        }
        if (conf.getAuxiliaryTerm().contains("project")) {
            Fitemss00 fitemss00 = new Fitemss00();
            fitemss00.setCitemname(item.getCitemName());
            fitemss00.setCitemcode(item.getCitemId());
            List<Fitemss00> fitemss00List = fitemss00Service.selectFitemss00List(fitemss00);
            if (!fitemss00List.isEmpty()) {
                accvouch.setCitemId(fitemss00List.get(0).getCitemcode());
            } else {
                //上级分类查询录入
                confList.forEach(confItem -> {
//                            if (!confItem.getcBusType4Id().equals(item.getcBusTypeValue()) && !confItem.getcBusType3Id().equals(item.getcBusTypeValue()) && !confItem.getcBusType2Id().equals(item.getcBusTypeValue()) && !confItem.getcBusType1Id().equals(item.getcBusTypeValue())) {
//                                return;
//                            }
                    if (confItem.getItemId().equals(item.getCitemId())) {
                        fitemss00.setCitemccode(confItem.getcBusType4Id());
                        addItemClass(confItem.getcBusType1Id(), confItem.getcBusType1(), "0", "1", fitemss97classService);
                        addItemClass(confItem.getcBusType2Id(), confItem.getcBusType2(), "0", "2", fitemss97classService);
                        addItemClass(confItem.getcBusType3Id(), confItem.getcBusType3(), "0", "3", fitemss97classService);
                        addItemClass(confItem.getcBusType4Id(), confItem.getcBusType4(), "1", "4", fitemss97classService);
                    }
//                            if (confItem.getcBusType3Id().equals(item.getcBusTypeValue())) {
//                                fitemss00.setCitemccode(confItem.getcBusType2());
//                                addItemClass(confItem.getcBusType2Id(), confItem.getcBusType2(), "1", "2");
//                                addItemClass(confItem.getcBusType1Id(), confItem.getcBusType1(), "0", "1");
//                            }
//                            if (confItem.getcBusType2Id().equals(item.getcBusTypeValue())) {
//                                fitemss00.setCitemccode(confItem.getcBusType1());
//                                addItemClass(confItem.getcBusType1Id(), confItem.getcBusType1(), "1", "1");
//                            }
                });

                fitemss00Service.insertFitemss00(fitemss00);
                accvouch.setCitemId(fitemss00.getCitemcode());
            }
            accvouch.setCitemClass("97");
        } else {
            accvouch.setCitemId(null);
            accvouch.setCitemClass(null);
        }
        if (conf.getAuxiliaryTerm().contains("gy")) {
            Vendor vendor = new Vendor();
            vendor.setcVenName(item.getCsupName());
            vendor.setcVenCode(StringUtils.substring(item.getPayee(), 0, 20));
            List<Vendor> vendorList = vendorService.selectVendorList(vendor);
            if (!vendorList.isEmpty()) {
                accvouch.setCsupId(vendorList.get(0).getcVenCode());
            } else {
                vendor.setcVenAbbName(item.getCsupName());
                vendor.setcVCCode("01");
                vendor.setcVenCode(StringUtils.substring(item.getPayee(), 0, 20));
                vendorService.insertVendor(vendor);
                accvouch.setCsupId(vendor.getcVenCode());
            }
        } else {
            accvouch.setCsupId(null);
        }
        if (conf.getAuxiliaryTerm().contains("gr")) {
            HrHiPerson hrHiPerson = new HrHiPerson();
            hrHiPerson.setCpsnName(item.getCpersonName());
            hrHiPerson.setCpsnNum(StringUtils.substring(item.getCpersonId(), 0, 20));
            List<HrHiPerson> hrHiPersonList = hrHiPersonService.selectHrHiPersonList(hrHiPerson);
            if (!hrHiPersonList.isEmpty()) {
                accvouch.setCpersonId(hrHiPersonList.get(0).getCpsnNum());
            } else {
                Department department = new Department();
                department.setcDepName(item.getPersonDept());
                department.setcDepCode(StringUtils.substring(item.getPersonDeptId(), 0, 12));
                List<Department> departmentList = departmentService.selectDepartmentList(department);
                if (departmentList.isEmpty()) {
                    department.setcDepFullName(item.getPersonDept());
                    department.setbDepEnd("1");
                    department.setiDepGrade("1");
                    department.setcDepCode(StringUtils.substring(item.getPersonDeptId(), 0, 12));
                    departmentService.insertDepartment(department);
                }
                hrHiPerson.setCdeptNum(StringUtils.substring(item.getPersonDeptId(), 0, 12));
                hrHiPerson.setbPsnPerson("1");
                hrHiPerson.setrPersonType("10");
                hrHiPerson.setrEmployState("10");
                hrHiPerson.setrSex("1");
                hrHiPersonService.insertHrHiPerson(hrHiPerson);
                Person person = new Person();
                person.setcPersonCode(hrHiPerson.getCpsnNum());
                person.setcPersonName(hrHiPerson.getCpsnName());
                person.setcDepCode(StringUtils.substring(item.getPersonDeptId(), 0, 12));
                person.setCid("01");
                person.setcAlias(hrHiPerson.getCpsnNum());
                person.setCvalue(hrHiPerson.getCpsnName());
                person.setbFreeStop(0);
                personService.insertPerson(person);
                accvouch.setCpersonId(hrHiPerson.getCpsnNum());
            }
        } else {
            accvouch.setCpersonId(null);
        }
    }

    static void insertUser(int[] i, IGlAccvouchService glAccvouchService, String type, GlAccvouch accvouch, GlAccvouch accvouchQuery) {
        if (!type.equals("1")) {
            GlAccvouch accvouchQueryReturn = glAccvouchService.selectGlAccvouchMaxId(accvouchQuery);
            if (accvouchQueryReturn == null || accvouchQueryReturn.getInoId() == null) {
                accvouch.setInoId(1);
            } else
                accvouch.setInoId(accvouchQueryReturn.getInoId() + 1);//当前年月最大编号
            i[0] = 0;
        }
    }

    static void addItemClass(String ccode, String cname, String end, String grade, IFitemss97classService fitemss97classService) {
        Fitemss97class fitemss97class = new Fitemss97class();
        fitemss97class.setCitemccode(ccode);
        List<Fitemss97class> fitemss97classList = fitemss97classService.selectFitemss97classList(fitemss97class);
        if (fitemss97classList.isEmpty()) {
            fitemss97class.setcItemCname(cname);
            fitemss97class.setbItemCend(end);
            fitemss97class.setiItemCgrade(grade);
            fitemss97classService.insertFitemss97class(fitemss97class);
        }
    }

    /**
     * 查询预算管理列表
     */
    @PreAuthorize("@ss.hasPermi('erp:budget:list')")
    @GetMapping("/list")
    public TableDataInfo list(LedyBudget ledyBudget) {
        startPage();
        List<LedyBudget> list = ledyBudgetService.selectLedyBudgetList(ledyBudget);
        return getDataTable(list);
    }

    /**
     * 导出预算管理列表
     */
    @PreAuthorize("@ss.hasPermi('erp:budget:export')")
    @Log(title = "预算管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, LedyBudget ledyBudget) {
        List<LedyBudget> list = ledyBudgetService.selectLedyBudgetList(ledyBudget);
        ExcelUtil<LedyBudget> util = new ExcelUtil<LedyBudget>(LedyBudget.class);
        util.exportExcel(response, list, "预算管理数据");
    }

    /**
     * 获取预算管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('erp:budget:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(ledyBudgetService.selectLedyBudgetById(id));
    }

    /**
     * 新增预算管理
     */
    @PreAuthorize("@ss.hasPermi('erp:budget:add')")
    @Log(title = "预算管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody LedyBudget ledyBudget) {
        return toAjax(ledyBudgetService.insertLedyBudget(ledyBudget));
    }

    /**
     * 修改预算管理
     */
    @PreAuthorize("@ss.hasPermi('erp:budget:edit')")
    @Log(title = "预算管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody LedyBudget ledyBudget) {
        if (ledyBudget.getIshare() == 1) {
            for (int i = 0; i < ledyBudget.getIperiod(); i++) {
                LedyBudgetShare budgetShare = new LedyBudgetShare();
                BeanUtil.copyProperties(ledyBudget, budgetShare);
                budgetShare.setIflagRe(0);
                budgetShare.setInoId(null);
                budgetShare.setDbillDate(null);
                budgetShare.setIperiod((long) i + 1);
                budgetShare.setMd(ledyBudget.getMd().divide(new BigDecimal(ledyBudget.getIperiod()), 2, RoundingMode.HALF_UP));
//                System.out.println(ledyBudget.getIyperiod()+"");
                budgetShare.setIyperiod(Timestamp.valueOf(DateUtil.toLocalDateTime(ledyBudget.getIyperiod()).plusMonths(i)));
                ledyBudgetShareService.insertLedyBudgetShare(budgetShare);
            }

        }
        return toAjax(ledyBudgetService.updateLedyBudget(ledyBudget));
    }

    /**
     * 删除预算管理
     */
    @PreAuthorize("@ss.hasPermi('erp:budget:remove')")
    @Log(title = "预算管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(ledyBudgetService.deleteLedyBudgetByIds(ids));
    }
}
